﻿using System;
using System.Linq;
using System.Text;
using DevExpress.Xpo;
using DevExpress.ExpressApp;
using System.ComponentModel;
using DevExpress.ExpressApp.DC;
using DevExpress.Data.Filtering;
using DevExpress.Persistent.Base;
using System.Collections.Generic;
using DevExpress.ExpressApp.Model;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;

namespace aztall.Module.BusinessObjects
{
	[RuleCombinationOfPropertiesIsUnique("ConfigDomain", DefaultContexts.Save, "Config.Oid,Domain.Oid,Role.Oid,User.Oid", CustomMessageTemplate = "Domain Code is duplicated.", SkipNullOrEmptyValues = false)]
	public class ConfigValue : RootObject
	{
		protected Config _Config;
		protected bool _IsInternal;
		protected Domain _Domain;
		protected Role _Role;
		protected User _User;
		protected string _Value;
		protected static IList<ConfigValue> _ConfigValues;

		public ConfigValue(Session session)
				: base(session)
		{
		}
		
		protected override void OnSaved()
		{
			base.OnSaved();
		}
		public override void AfterConstruction()
		{
			base.AfterConstruction();

		}
		[Association("Config-ConfigValue")]
		[ModelDefault("AllowEdit", "False"), Browsable(false)]
		public Config Config
		{
			get { return _Config; }
			set { SetPropertyValue(nameof(Config), ref _Config, value); }
		}

		#region public properties
		[Index(1), VisibleInListView(false), VisibleInLookupListView(false)]
		public string Description
		{
			get { return string.Format("{0}: {1}", Config.ConfigName, Config.Description); }
		}
		[Index(2), ToolTip("Blank for all")]
		public Domain Domain
		{
			get { return _Domain; }
			set { SetPropertyValue(nameof(Domain), ref _Domain, value); }
		}
		[Index(3), ToolTip("Blank for all")]
		public Role Role
		{
			get { return _Role; }
			set { SetPropertyValue(nameof(Role), ref _Role, value); }
		}
		[Index(4), ToolTip("Blank for all")]
		public User User
		{
			get { return _User; }
			set { SetPropertyValue(nameof(User), ref _User, value); }
		}

		[Index(6), Size(128)]
		public string Value
		{
			get { return _Value; }
			set { SetPropertyValue(nameof(Value), ref _Value, value); }
		}
		#endregion
		public static string FindValue(Session session, string configName)
		{
			ConfigValue result = null;
			if (_ConfigValues == null)
				_ConfigValues = new XPCollection<ConfigValue>(session);
			//var configValues = new XPCollection<ConfigValue>(session, CriteriaOperator.Parse("Config.ConfigName = ?", configName)).ToList();
			User u = Env.GetCurrentUser(session);

			//by user, role, domain
			result = _ConfigValues.Where(c => c.User != null && c.User.Oid == u.Oid && c.Role != null && u.Roles.Any(r => r == c.Role) && c.Domain != null && c.Domain.Oid == Env.CurrentDomainOid).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by user, role
			result = _ConfigValues.Where(c => c.User != null && c.User.Oid == u.Oid && c.Role != null && u.Roles.Any(r => r == c.Role) && c.Domain == null).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by user, Domain
			result = _ConfigValues.Where(c => c.User != null && c.User.Oid == u.Oid && c.Role == null && c.Domain != null && c.Domain != null && c.Domain.Oid == Env.CurrentDomainOid).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by user
			result = _ConfigValues.Where(c => c.User != null && c.User.Oid == u.Oid && c.Role == null && c.Domain == null).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by role, domain
			result = _ConfigValues.Where(c => c.User == null && c.Role != null && u.Roles.Any(r => r == c.Role) && c.Domain != null && c.Domain.Oid == Env.CurrentDomainOid).FirstOrDefault();
			if (result != null)
				return result.Value;

			// by role
			result = _ConfigValues.Where(c => c.User == null && c.Role != null && u.Roles.Any(r => r == c.Role) && c.Domain == null).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by domain
			result = _ConfigValues.Where(c => c.User == null && c.Role == null && c.Domain != null && c.Domain.Oid == Env.CurrentDomainOid).FirstOrDefault();
			if (result != null)
				return result.Value;

			//by default
			result = _ConfigValues.Where(c => c.User == null && c.Role == null && c.Domain == null).FirstOrDefault();

			return result.Value;
		}

}
}
